package com.itheima.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itheima.dao.GoodsDao;
import com.itheima.goods.pojo.Goods;
import com.itheima.service.GoodsService;
import com.itheima.util.ElasticSearchUtils;
import entity.Result;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import springfox.documentation.spring.web.json.Json;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service("goodsService")
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class GoodsServiceImpl implements GoodsService {
    //注入dao层对象
    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private ElasticSearchUtils elasticSearchUtils;

    //查询所有商品信息
    @Override
    public Result findAll() throws IOException {
        //创建wrapper对象
        LambdaQueryWrapper<Goods> wrapper = Wrappers.lambdaQuery(Goods.class);
        //查询
        List<Goods> goods = goodsDao.selectList(wrapper);
        //将查询结果存入elasticSearch中
        BulkRequest request = new BulkRequest("goods"); //创建请求对象
        //遍历集合
        for (Goods good : goods) {
            IndexRequest indexRequest = new IndexRequest();
            //设置文档id
            indexRequest.id(good.getId().toString());
            //将goods对象转换为json字符串
            String goodJsonString = JSON.toJSONString(good);
            indexRequest.source(goodJsonString,XContentType.JSON);
            //添加条件对象至请求对象中
            request.add(indexRequest);
        }
        //提交请求
        RestHighLevelClient client = elasticSearchUtils.createClient();
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        //返查询结果
        return new Result(true,200,null,goods);
    }

    //添加商品
    @Override
    @Transactional(propagation = Propagation.REQUIRED,readOnly = false)
    public Result add(Goods goods) {
        //调用dao层插入方法
        int cowCount = goodsDao.insert(goods);
        //判断是否擦添加成功
        if(cowCount > 0 ){
            //添加成功
            return new Result(true,200,null,null);
        }
        //添加失败
        return new Result(false,404,"添加失败",null);
    }

    //分页查询
    @Override
    public Result findPage(Integer page, Integer size,Goods goods) throws IOException {
        //创建ElaticSearch客户端对象
        RestHighLevelClient client = new ElasticSearchUtils().createClient();
        //创建请求对象
        SearchRequest searchRequest = new SearchRequest("goods");
        //创建查询条件对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //封装查询条件
        searchSourceBuilder.query(QueryBuilders.matchAllQuery()); //查询所有
        //分页
        searchSourceBuilder.from(page);
        searchSourceBuilder.size(size);
        //将查询条件对象赋值给请求对象
        searchRequest.source(searchSourceBuilder);
        //发送查询请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        ArrayList<String> list = new ArrayList<>();
        //处理查询结果
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            list.add(sourceAsString);
        }
        //关闭client
        client.close();
        return new Result(true,200,null,list);
    }

    //根据id查询
    @Override
    public Result findById(Integer id) {
        //创建wrapper对象
        LambdaQueryWrapper<Goods> wrapper = Wrappers.lambdaQuery(Goods.class);
        //封装查询条件
        wrapper.eq(Goods::getId,id);
        //查询
        Goods goods = goodsDao.selectOne(wrapper);
        //返回查询结果
        return new Result(true,200,null,goods);
    }

    //根据id修改商品信息
    @Override
    @Transactional(propagation = Propagation.REQUIRED,readOnly = false)
    public Result update(Integer id, Goods goods) {
        goods.setId(id);
        //调用dao层更新方法
        int cowCount = goodsDao.updateById(goods);
        //判断是否擦添加成功
        if(cowCount > 0 ){
            //修改成功
            return new Result(true,200,null,null);
        }
        //添加失败
        return new Result(false,404,"修改失败",null);
    }

    //根据id删除商品信息
    @Override
    @Transactional(propagation = Propagation.REQUIRED,readOnly = false)
    public Result delete(Integer id) {
        //调用dao层删除方法
        int cowCount = goodsDao.deleteById(id);
        //判断是否擦添加成功
        if(cowCount > 0 ){
            //删除成功
            return new Result(true,200,null,null);
        }
        //删除失败
        return new Result(false,404,"删除失败",null);
    }






}
